﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PlayBox.DataClasses;
using System.Windows.Forms;

namespace PlayBox
{
    public static class User
    {
        private static FileSystem _fileSystem = new FileSystem ();

        private static UserData _userData;
        /// <summary>
        /// Daten des derzeitig angemeldeten Benutzers
        /// </summary>
        public static UserData UserData
        {
            get
            {
                return _userData;
            }
        }

        private static bool _isLoggedIn = false;
        /// <summary>
        /// Gibt an, ob ein Benutzer derzeit angemeldet ist
        /// </summary>
        public static bool IsLoggedIn
        {
            get
            {
                return _isLoggedIn;
            }
        }

        private static bool _isAutoLoggedIn = false;
        /// <summary>
        /// Gibt an, ob der derzeitig angemeldete Benutzer automatisch angemeldet wurde
        /// </summary>
        public static bool IsAutoLoggedIn
        {
            get
            {
                return _isAutoLoggedIn;
            }
        }

        /// <summary>
        /// Meldet Benutzer an
        /// </summary>
        /// <param name="username">Benutzername</param>
        /// <param name="password">Passwort</param>
        /// <returns></returns>
        public static bool LogIn(String username, String password)
        {
            return LogIn(username, password, false);
        }

        /// <summary>
        /// Meldet Benutzer an
        /// </summary>
        /// <param name="username">Benutzername</param>
        /// <param name="password">Passwort</param>
        /// <param name="autoLogin">Beim nächsten Start automatisch anmelden</param>
        /// <returns></returns>
        public static bool LogIn(String username, String password, bool autoLogin)
        {
            // -----------------------------------
            // Lokal anmelden
            // -----------------------------------

            UserData data = _fileSystem.GetUserData(username);

            // Gibts Benutzer nicht?
            if (data == null)
                return false;

            // Userklasse zum Vergleichen anlegen
            UserData enteredUser = new UserData();
            enteredUser.Salt = data.Salt;
            enteredUser.SetPassword(password);

            // Vergleichen
            if (enteredUser.Hash != data.Hash)
                return false;
            
            // Erfolgreich
            _userData = data;
            _isLoggedIn = true;

            if (autoLogin)
                _fileSystem.LastUser = _userData;
            else
                _fileSystem.LastUser = null;

            // -----------------------------------
            // Online merken
            // -----------------------------------

            ServerConnection.Current.Username = username;
            ServerConnection.Current.Password = password;

            return true;
        }        

        /// <summary>
        /// Versucht, zuletzt angemeldeten Benutzer nochmal anzumelden
        /// </summary>
        /// <returns></returns>
        public static bool LogInLastUser ()
        {
            // Letzten Benutzer holen
            var user = _fileSystem.LastUser;
            if (user == null)
                return false;

            // -----------------------------------
            // Lokal anmelden
            // -----------------------------------

            UserData data = _fileSystem.GetUserData(user.Username);

            // Gibts Benutzer nicht?
            if (data == null)
                return false;
            
            // Vergleichen
            if (user.Hash != data.Hash)
                return false;

            // Erfolgreich
            _userData = data;
            _isLoggedIn = true;
            _isAutoLoggedIn = true;

            // -----------------------------------
            // Online merken
            // -----------------------------------

            ServerConnection.Current.Username = user.Username;

            return true;
        }

        /// <summary>
        /// Registriert einen neuen Benutzer
        /// </summary>
        /// <param name="username">Benutzername</param>
        /// <param name="password">Passwort</param>
        /// <returns></returns>
        public static bool Register(String username, String password)
        {
            UserData data = new UserData();
            data.Username = username;
            data.SetPassword(password);

            // -----------------------------------
            // Online registrieren
            // -----------------------------------

            try
            {
                bool success = ServerConnection.Current.RegisterUser(username, data.Hash, data.Salt);

                if (!success)
                {
                    MessageBox.Show("Serverregistrierung fehlgeschlagen.", "Fehler", MessageBoxButtons.OK);

                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Serverregistrierung fehlgeschlagen.\n" + ex.Message, "Fehler", MessageBoxButtons.OK);
                return false;
            }

            // Key erstellen
            TPM.generateUserKey(data.Username);

            // Lokal schreiben
            _fileSystem.SetUserData(data);

            // Erfolgreich
            _userData = data;
            _isLoggedIn = true;

            // -----------------------------------
            // Online merken
            // -----------------------------------

            ServerConnection.Current.Username = username;
            ServerConnection.Current.Password = password;

            return true;
        }

        /// <summary>
        /// Ändert das Passwort für den derzeitig angemeldeten Benutzer
        /// </summary>
        /// <param name="username">Benutzername</param>
        /// <param name="password">Neues Passwort</param>
        /// <returns></returns>
        public static bool ChangePassword(String username, String password)
        {
            if (!_isLoggedIn)
                throw new Exception("Not logged in");

            UserData data = new UserData();
            data.Username = username;
            data.Salt = _userData.Salt;
            data.SetPassword(password);

            // -----------------------------------
            // Online registrieren
            // -----------------------------------

            try
            {
                bool success = ServerConnection.Current.ChangePassword (data.Hash, data.Salt);

                if (!success)
                {
                    MessageBox.Show("Passwort ändern fehlgeschlagen.", "Fehler", MessageBoxButtons.OK);

                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Serveraufruf fehlgeschlagen.\n" + ex.Message, "Fehler", MessageBoxButtons.OK);
                return false;
            }

            // Lokal schreiben
            _fileSystem.SetUserData(data);

            // Erfolgreich
            _userData = data;

            // -----------------------------------
            // Online merken
            // -----------------------------------

            ServerConnection.Current.Password = password;

            return true;
        }

        /// <summary>
        /// Meldet den Benutzer ab
        /// </summary>
        public static void LogOut ()
        {
            _userData = null;
            _isLoggedIn = false;
            _isAutoLoggedIn = false;

            _fileSystem.LastUser = null;
        }

    }
}
